{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "参考underactuated包中极限环的例子。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pydrake\n",
    "import underactuated\n",
    "\n",
    "from pydrake.examples.van_der_pol import VanDerPolOscillator\n",
    "from pydrake.all import DirectCollocation, PiecewisePolynomial, Solve\n",
    "\n",
    "plant = VanDerPolOscillator()\n",
    "context = plant.CreateDefaultContext()\n",
    "\n",
    "dircol = DirectCollocation(plant,\n",
    "                           context,\n",
    "                           num_time_samples=61,\n",
    "                           minimum_timestep=0.01,\n",
    "                           maximum_timestep=0.5)\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在使用过程中发现缺少有些依赖。经过查询，发现可以直接在notebook中操作安装。\n",
    "方法如下：\n",
    "在cell中直接写命令，并在命令前加“!”即可。\n",
    "如：\n",
    "!pip install --user scipy\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(-3.0, 3.0)"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "%matplotlib inline\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "\n",
    "#from jupyter_setup import setup_underactuated\n",
    "#setup_underactuated()\n",
    "\n",
    "#from underactuated.jupyter import SetupMatplotlibBackend\n",
    "#plt_is_interactive = SetupMatplotlibBackend()\n",
    "\n",
    "# Constrain all timesteps, $h[k]$, to be equal, so the trajectory breaks are evenly distributed.\n",
    "dircol.AddEqualTimeIntervalsConstraints()\n",
    "\n",
    "# Initial state on the surface of section (and velocity > .1).\n",
    "dircol.AddBoundingBoxConstraint([0., 0.1], [0., 10.], dircol.initial_state())\n",
    "\n",
    "# Periodicity constraint.\n",
    "# TODO(russt): Replace this with the vectorized version pending drake #8315.\n",
    "dircol.AddLinearConstraint(dircol.final_state()[0] == dircol.initial_state()[0])\n",
    "dircol.AddLinearConstraint(dircol.final_state()[1] == dircol.initial_state()[1])\n",
    "\n",
    "# Help the solver with an initial guess (circular trajectory).\n",
    "samples = np.linspace(0, 2 * np.pi, 10)\n",
    "x_guess = np.vstack(\n",
    "    ([2 * np.sin(t) for t in samples], [2 * np.cos(t) for t in samples]))\n",
    "initial_x_trajectory = PiecewisePolynomial.FirstOrderHold(samples, x_guess)\n",
    "\n",
    "dircol.SetInitialTrajectory(PiecewisePolynomial(), initial_x_trajectory)\n",
    "\n",
    "fig = plt.figure()\n",
    "h, = plt.plot([], [], \".-\")\n",
    "plt.xlim((-2.5, 2.5))\n",
    "plt.ylim((-3., 3.))\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x7f2a6a4b0630>]"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "def draw_trajectory(t, x):\n",
    "    h.set_xdata(x[0, :])\n",
    "    h.set_ydata(x[1, :])\n",
    "    fig.canvas.draw()\n",
    "    if plt.get_backend() == u\"MacOSX\":\n",
    "        plt.pause(1e-10)\n",
    "\n",
    "if plt_is_interactive:\n",
    "    dircol.AddStateTrajectoryCallback(draw_trajectory)\n",
    "\n",
    "result = Solve(dircol)\n",
    "assert result.is_success()\n",
    "\n",
    "x_trajectory = dircol.ReconstructStateTrajectory(result)\n",
    "\n",
    "x_knots = np.hstack([\n",
    "    x_trajectory.value(t) for t in np.linspace(x_trajectory.start_time(),\n",
    "                                               x_trajectory.end_time(), 100)\n",
    "])\n",
    "plt.plot(x_knots[0, :], x_knots[1, :])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
